package com.yanftch.hdc_tools.insertcode.settings

import com.intellij.openapi.options.Configurable
import com.intellij.openapi.project.Project
import com.yanftch.hdc_tools.common.*
import com.yanftch.hdc_tools.insertcode.bean.CodeBean
import com.yanftch.hdc_tools.insertcode.storage.InsertCodeState
import com.yanftch.hdc_tools.insertcode.ui.InsertCodeSettingsForm
import com.yanftch.hdc_tools.insertcode.util.FileUtils
import com.yanftch.hdc_tools.insertcode.util.GsonUtils
import com.yanftch.hdc_tools.org.json.JSONObject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.util.*
import javax.swing.JComponent
import javax.swing.JOptionPane
import javax.swing.SwingWorker
import kotlin.coroutines.EmptyCoroutineContext

class InsertCodeSettings(val project: Project) : Configurable {
    private val defaultName = "添加自定义模板"
    private val validateName = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

    private val form = InsertCodeSettingsForm()
    private val component: JComponent
    private var fullList = mutableListOf<CodeBean>()

    init {
        component = form.mainPanel
        // jar 中的默认配置数据
        loadFileInBackground( )
    }

    private fun loadFileInBackground() {
        val worker = object : SwingWorker<List<CodeBean>, String>() {
            override fun doInBackground(): List<CodeBean> {
                val result = mutableListOf<CodeBean>()
                try {
                    // 默认的配置数据
                    val defaultList = FileUtils.getList()
                    val loadJsonFromFile = InsertCodeState.loadJsonFromFile()
                    // 用户自定义的配置数据
                    val userList :List<CodeBean> = GsonUtils.jsonToList(loadJsonFromFile, CodeBean::class.java)

                    val mergeLists = mergeLists(userList, defaultList)
                    result.addAll(mergeLists)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                return result
            }

            override fun done() {
                try {
                    val data:List<CodeBean> = get() // 获取后台任务的结果
                    val sortedBy = data.sortedBy { it.name.lowercase() }
                    fullList.addAll(sortedBy)
                    if (fullList.isNotEmpty()) {
                        fullList.forEach {
                            form.comboBox.addItem(it)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
        worker.execute()
    }


    override fun createComponent() = component

    override fun isModified(): Boolean {
//        return state.bundleName.trim() != form.bundleName.text.trim() || state.defaultAbility.trim() != form.defaultAbility.text.trim() || state.hdcPath.trim() != form.hdcPath.text.trim()
        return true
    }

    private fun saveToJsonFile() {
        val tmpList = mutableListOf<CodeBean>()
        fullList.forEach {
            tmpList.add(it)
        }
        // 排序
        tmpList.sortBy { it.name.lowercase(Locale.getDefault()) }
        val jsonString = GsonUtils.toJson(tmpList)
        InsertCodeState.saveJsonToFile(jsonString)
    }


    override fun apply() {
        val diyName = form.diyName.text.trim()

        // 如果name已经存在于 fullList 中，那么就是修改，而不是新增了
        val selectedItem = form.comboBox.selectedItem as? CodeBean

        // 自定义名称为默认名称，那么就是修改之前的
        if (selectedItem != null && defaultName == diyName) {
            // 修改
            selectedItem.value = form.diyCodeContent.text
            val bean = fullList.findLast { it.name == selectedItem.name }
            bean?.value = form.diyCodeContent.text
            saveNew(bean)
            saveToJsonFile()
            return
        }
        // 自定义名称与已有的重复，则修改已有的
        val findLast = fullList.findLast { it.name == form.diyName.text }
        if (findLast != null) {
            // 修改
            findLast.value = form.diyCodeContent.text
            val bean = fullList.findLast { it.name == form.diyName.text }
            bean?.value = form.diyCodeContent.text
            saveNew(bean)
            saveToJsonFile()
        } else {
            val f = diyName.first()
            val b = validateName.contains(f)
            if (!b) {
                copyToClipboard(form.diyCodeContent.text.trim())
                JOptionPane.showMessageDialog(
                    component,
                    "模板名必须是字母开头！否则保存无效 \n\n 当前模板代码已拷贝到剪贴板,修改模板名继续",
                    "⚠️警告",
                    JOptionPane.WARNING_MESSAGE
                )
                return
            }
            // 直接新增
            val value = form.diyCodeContent.text
            if (diyName.isNotEmpty() && value.isNotEmpty()) {
                val bean = CodeBean(diyName, value)
                fullList.add(bean)
                form.comboBox.addItem(bean)
                saveNew(bean)
                saveToJsonFile()
            }
        }
    }

    private fun saveNew(bean: CodeBean?) {
        bean?.let {
            val obj = JSONObject()
            obj.put("name", it.name)
            obj.put("value", it.value)
            obj.put("pluginVersion", getPluginVersion())
            obj.put("ideInfo", JSONObject(getIDEInfo()))

            val scope = CoroutineScope(EmptyCoroutineContext)
            scope.launch {
                upload(it.name, obj)
            }
        }
    }

    suspend fun upload(name: String, obj: JSONObject) {
        NetUtil.c(name, obj.toString(4))
    }

    override fun reset() {
        form.diyName.text = defaultName
        form.diyCodeContent.text = ""
    }

    override fun getDisplayName() = "InsertCodeSettings"
}